// ==UserScript==
// @name         瑞智工具
// @version      1.6
// @description  从当前页面解析出账号信息到剪切板，并在弹窗中添加辅助插入按钮
// @author       s0ing
// @match        *://*/*
// @updateURL    https://gitee.com/s0ing/tampermonkey_script/raw/main/ex_author.user.js
// @downloadURL  https://gitee.com/s0ing/tampermonkey_script/raw/main/ex_author.user.js
// @grant        GM_setClipboard
// @grant        GM_getClipboard
// @run-at       document-end
// ==/UserScript==

const RETRY_INTERVAL = 1000;
const MAX_ATTEMPTS = 10;

// 复制内容到剪贴板的函数
function copyToClipboard(content) {
    if (typeof GM_setClipboard !== 'undefined') {
        GM_setClipboard(content);
    } else {
        const textArea = document.createElement('textarea');
        textArea.value = content;
        document.body.appendChild(textArea);
        textArea.select();
        document.execCommand('copy');
        document.body.removeChild(textArea);
    }
}

// 读取剪贴板内容的函数（兼容Tampermonkey和浏览器）
function getClipboardContent() {
    // 优先使用 Tampermonkey 的 GM_getClipboard
    if (typeof GM_getClipboard !== 'undefined') {
        try {
            return GM_getClipboard();
        } catch (e) {
            console.error('GM_getClipboard failed:', e);
            return null;
        }
    }
    // 回退到 navigator.clipboard.readText（异步）
    else if (navigator.clipboard && typeof navigator.clipboard.readText === 'function') {
        return navigator.clipboard.readText()
            .then(text => text)
            .catch(err => {
                console.error('Failed to read clipboard using navigator.clipboard:', err);
                return null;
            });
    }
    // 如果两者都不可用，返回 null
    else {
        console.warn('Clipboard API not supported in this environment.');
        return null;
    }
}


// 微信信息提取
function getWeixinInfo() {
    const globalWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    return {
        user_name: globalWindow.globalThis.nickname,
        user_id: globalWindow.globalThis.user_name,
        user_biz: globalWindow.globalThis.biz
    };
}

// 百家号信息提取
function getBaijiahaoInfo() {
    const globalWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    return {
        user_name: globalWindow.jsonData["bsData"]["superlanding"][1]["itemData"]["name"],
        user_id: globalWindow.jsonData["bsData"]["superlanding"][1]["itemData"]["third_id"],
        user_biz: globalWindow.jsonData["bsData"]["superlanding"][1]["itemData"]["uk"]
    };
}

// 百度作者信息提取
function getAuthorBaiduInfo() {
    const globalWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    return {
        user_name: globalWindow.runtime["user"]["display_name"],
        user_id: globalWindow.runtime["user"]["bjh_id"],
        user_biz: globalWindow.runtime["user"]["uk"]
    };
}

// 百度 MBD 信息提取
function getMbdBaiduInfo() {
    const globalWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;

    let user_name;
    try {
        user_name = globalWindow.jsonData["author"]["name"];
    } catch (e) {
        user_name = globalWindow.jsonData["bsData"]["superlanding"][0]["itemData"]["infoBaiJiaHao"]["name"]
    }

    let user_id;
    try {
        user_id = globalWindow.jsonData["author"]["third_id"];
    } catch (e) {
        user_id = globalWindow.jsonData["bsData"]["superlanding"][0]["itemData"]["infoBaiJiaHao"]["third_id"];
    }

    let user_biz;
    try {
        user_biz = globalWindow.jsonData["author"]["uk"];
    } catch (e) {
        user_biz = globalWindow.jsonData["bsData"]["superlanding"][1]["itemData"]["uk"]
    }

    return {
        user_name: user_name,
        user_id: user_id,
        user_biz: user_biz
    };
}

// 微博信息提取
function getWeiboInfo() {
    const titleElement = document.querySelector('title');
    const url = window.location.href;
    const user_name = titleElement.textContent.split('@')[1].split('的个人')[0].split('的微博')[0];
    const user_id = url.replace('https://weibo.com/u/', '').replace('https://weibo.com/', '').split('/')[0].split('?')[0];
    const user_biz = null;
    return {user_name, user_id, user_biz};
}

// 大鱼号信息提取
function getDaYvHaoUCInfo() {
    const url = window.location.href;
    if (url.includes('mparticle.uc.cn')) {

        const xpathExpression = '//div[contains(@class,"article-userInfoName")]';
        const result = document.evaluate(xpathExpression, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
        let user_name;
        if (result.singleNodeValue) {
            user_name = result.singleNodeValue.textContent;
        } else {
            user_name = null;
        }
        const user_id = url.split('wm_id=')[1].split('&')[0];
        const user_biz = user_id;
        return {user_name, user_id, user_biz};
    } else {
        const user_name = document.querySelector('title').textContent;
        const user_id = url.split('mid=')[1].split('&')[0];
        const user_biz = user_id;
        return {user_name, user_id, user_biz};
    }
}

// 小红书信息提取
function getXiaoHongShuInfo() {
    const user_name = document.querySelector('.user-name').textContent;
    const user_id = document.querySelector('.user-redId').textContent.replace('小红书号：', '');
    const user_biz = window.location.href.split('profile/')[1].split('?')[0];
    return {user_name, user_id, user_biz}
}

// B 站信息提取
function getBiLiBiLiInfo() {

    if (window.location.href.includes('space.bilibili.com')) {
        const user_name = document.querySelector('.nickname').textContent;
        const user_id = window.location.href.split('space.bilibili.com/')[1];
        const user_biz = user_id;
        return {user_name, user_id, user_biz}
    } else {
        const user_name = document.querySelector('.up-name').textContent.trim();
        const user_id = document.querySelector('.up-name').href.split('space.bilibili.com/')[1];
        const user_biz = user_id;
        return {user_name, user_id, user_biz}
    }
}

// 今日头条信息提取
function getToutiaoInfo() {

    let RENDER_DATA = document.querySelector('#RENDER_DATA').innerHTML;
    // url 解码
    RENDER_DATA = decodeURIComponent(RENDER_DATA);
    // 转为 JSON
    RENDER_DATA = JSON.parse(RENDER_DATA);
    let user_id
    let user_name
    let user_biz

    try {
        try {
            user_id = RENDER_DATA["data"]["initialVideo"]["log_pb"]["author_id"];
            user_name = RENDER_DATA["data"]["initialVideo"]["userInfo"]["name"]
            user_biz = RENDER_DATA["data"]["initialVideo"]["userInfo"]["userId"]
        } catch (e) {
            user_id = RENDER_DATA["data"]["mediaInfo"]["unsafeUserId"]
            user_name = RENDER_DATA["data"]["mediaInfo"]["name"]
            user_biz = RENDER_DATA["data"]["mediaInfo"]["userId"]
            // let avatarUrl = RENDER_DATA["data"]["mediaInfo"]["avatarUrl"]
        }
    } catch (e) {
        user_id = RENDER_DATA["data"]["profileUserInfo"]["mediaId"];
        user_name = RENDER_DATA["data"]["profileUserInfo"]["screenName"]
        user_biz = RENDER_DATA["data"]["profileUserInfo"]["userId"]
    }


    return {user_name, user_id, user_biz};
}

// 抖音信息提取
function getDouyinInfoAsyncFunction() {
    return new Promise((resolve) => {
        let attemptCount = 0;
        const attempt = () => {
            attemptCount++;
            console.log(`第 ${attemptCount} 次尝试提取信息`);
            try {
                const titleElement = document.querySelector('title');
                const bodyElement = document.querySelector('body');
                const url = window.location.href;
                const user_name = titleElement.textContent.split('的抖音')[0].trim();
                const user_id = bodyElement.textContent.match(/抖音号：(.*)\n/)[1].trim();
                const user_biz = url.split('user/')[1].split('?')[0];

                if (!user_name || !user_id) {
                    console.log('提取信息失败');
                    throw new Error('提取信息失败');
                } else {
                    console.log(user_name, user_id, user_biz);
                    console.log('提取信息成功');
                    resolve({user_name, user_id, user_biz});
                }
            } catch (e) {
                if (attemptCount < MAX_ATTEMPTS) {
                    console.error(`第 ${attemptCount} 次提取信息失败，错误信息:`, e);
                    setTimeout(attempt, RETRY_INTERVAL);
                } else {
                    console.error('达到最大重试次数，提取信息失败');
                    resolve(null);
                }
            }
        };
        attempt();
    });
}

// 查找包含指定文本的指定标签元素
function findTextInHtml(tag_name, targetText) {
    const allSpans = document.querySelectorAll(tag_name);
    return Array.from(allSpans).find(span => span.textContent === targetText);
}

// 处理找到的 span 元素，删除其父级无属性 div 元素
function handleMatchedSpan(matchedSpan) {
    if (matchedSpan) {
        console.log('找到匹配的 span 元素:', matchedSpan);
        // 从匹配的 span 元素开始向上遍历父级元素
        let currentElement = matchedSpan.parentElement;
        while (currentElement) {
            if (currentElement.tagName === 'DIV' && currentElement.attributes.length === 0) {
                console.log('找到没有任何属性的 div 父级元素:', currentElement);
                // 可以在这里对找到的 div 元素进行操作，比如改变样式
                currentElement.remove();
                break;
            }
            currentElement = currentElement.parentElement;
        }
    } else {
        console.log('未找到匹配的 span 元素');
    }
}

// 创建 MutationObserver 实例
const observer = new MutationObserver((mutationsList) => {
    for (const mutation of mutationsList) {
        if (mutation.type === 'childList') {
            const addedNodes = mutation.addedNodes;
            for (let i = 0; i < addedNodes.length; i++) {
                const node = addedNodes[i];
                if (node.nodeType === Node.ELEMENT_NODE) {
                    const matchedSpan = findTextInHtml('span', '创建新账户');
                    handleMatchedSpan(matchedSpan);
                }
            }
        }
    }
});

// Facebook 信息提取
function getFaceBookInfo() {

    // 创建一个监听器，如果当前页面中出现了 '创建新账户' 的 span 元素，就删除其父级 div 元素
    const config = {childList: true, subtree: true};

    // 开始观察文档根节点
    observer.observe(document.documentElement, config)

    const initialMatchedSpan = findTextInHtml('span', '创建新账户');
    handleMatchedSpan(initialMatchedSpan);

    const user_name = document.querySelector('title').textContent.split(' |')[0];
    const user_id = window.location.href.split('facebook.com/')[1].split('/')[0];
    const user_biz = user_id;
    return {user_name, user_id, user_biz};
}

// YouTube 信息提取
function getYouTuBeInfo() {
    try {
        const user_id = document.querySelector('#above-the-fold').querySelector('[aria-label="视频"]').href.split('channel/')[1].split('/')[0];
        const user_name = document.querySelector('#above-the-fold').querySelector('#text').title;
        const user_biz = user_id
        console.log('--->', user_name, user_id, user_biz);
        return {user_name, user_id, user_biz};
    } catch (e) {
        console.log('youtube 作者页面');
        const user_name = ytInitialData.metadata.channelMetadataRenderer.title;
        const user_id = ytInitialData.metadata.channelMetadataRenderer.externalId;
        const user_biz = user_id;
        return {user_name, user_id, user_biz};
    }
}

// X 站信息提取
function getXInfo() {
    try {
        let user_name_info = document.querySelector('[data-testid="UserProfileSchema-test"]').textContent;
        user_name_info = JSON.parse(user_name_info);
        const user_name = user_name_info.mainEntity.givenName;
        const user_id = user_name_info.mainEntity.additionalName;
        const user_biz = user_id;
        return {user_name, user_id, user_biz};
    } catch (e) {
        const user_name = document.querySelector('[data-testid="User-Name"]').querySelectorAll('span')[1].textContent;
        const user_id = document.querySelector('[data-testid="User-Name"]').querySelector('[role="link"]').href;
        const user_biz = user_id;
        return {user_name, user_id, user_biz};
    }
}

async function exInfo() {
    const url = window.location.href;
    let authorInfo;

    const urlExtractMap = {
        'mp.weixin.qq.com/': {
            extractFunction: getWeixinInfo,
            plat: '微信'
        },
        'baijiahao.baidu.com/': {
            extractFunction: getBaijiahaoInfo,
            plat: '百家号'
        },
        'author.baidu.com/': {
            extractFunction: getAuthorBaiduInfo,
            plat: '百家号'
        },
        'mbd.baidu.com/': {
            extractFunction: getMbdBaiduInfo,
            plat: '百家号'
        },
        'weibo.com/': {
            extractFunction: getWeiboInfo,
            plat: '微博'
        },
        'www.douyin.com/user': {
            extractFunction: getDouyinInfoAsyncFunction,
            plat: '抖音'
        },
        'www.toutiao.com/': {
            extractFunction: getToutiaoInfo,
            plat: '今日头条'
        },
        '.uc.cn/': {
            extractFunction: getDaYvHaoUCInfo,
            plat: '大鱼号'
        },
        'xiaohongshu.com/user/profile': {
            extractFunction: getXiaoHongShuInfo,
            plat: '小红书'
        },
        'bilibili.com/': {
            extractFunction: getBiLiBiLiInfo,
            plat: 'B站'
        },
        'facebook.com/': {
            extractFunction: getFaceBookInfo,
            plat: 'Facebook'
        },
        'youtube.com/': {
            extractFunction: getYouTuBeInfo,
            plat: 'Youtube'
        },
        'x.com/': {
            extractFunction: getXInfo,
            plat: 'Twitter'
        }
    };



    // 遍历映射对象，查找匹配的 URL 关键字
    for (const [keyword, extractFunctionMap] of Object.entries(urlExtractMap)) {
        if (url.includes(keyword)) {
            let extractFunction;
            extractFunction = extractFunctionMap.extractFunction
            if (extractFunction.constructor.name === 'AsyncFunction' || extractFunction.name.includes('AsyncFunction')) {
                // 如果是异步函数，使用重试函数调用
                authorInfo = await retryFunction(extractFunction);
            } else {
                // 如果是同步函数，将其包装成异步函数后使用重试函数调用
                const syncFunctionWrapper = async () => extractFunction();
                authorInfo = await retryFunction(syncFunctionWrapper);
            }
            authorInfo.plat = extractFunctionMap.plat
            break;
        }
    }
    window.authorInfo = authorInfo;
    return authorInfo;
}

// 通用重试函数
async function retryFunction(func, maxAttempts = MAX_ATTEMPTS, interval = RETRY_INTERVAL) {
    let attempt = 0;
    while (attempt < maxAttempts) {
        try {
            const result = await func();
            if (result && result.user_id && result.user_name) {
                return result;
            } else {
                console.log('提取信息失败');
                throw new Error('提取信息失败');
            }
        } catch (error) {
            console.error(`第 ${attempt + 1} 次调用函数失败，错误信息:`, error);
        }
        attempt++;
        if (attempt < maxAttempts) {
            await new Promise(resolve => setTimeout(resolve, interval));
        }
    }
    console.error('达到最大重试次数，函数调用失败');
    return null;
}

// 创建复制按钮
function createCopyButton(text, content, backgroundColor) {
    // 查找现有的按钮（通过 ID）
    // 创建新按钮
    const copyButton = document.createElement('button');
    copyButton.id = text;
    // 根据内容设置按钮显示的文本
    let displayText = text === '复制全部' ? text : content;

    const maxLength = 12; // 假设按钮最多显示 12 个字符
    if (displayText.length > maxLength && content!== '复制全部') {
        displayText = displayText.slice(0, maxLength - 3) + '...';
    }
    copyButton.textContent = displayText;
    copyButton.style.position = 'fixed';
    copyButton.style.right = '10px';
    copyButton.style.zIndex = '9999';
    copyButton.style.fontSize = '16px';
    copyButton.style.padding = '10px';
    copyButton.style.width = '120px';
    copyButton.style.textAlign = 'center';
    copyButton.style.border = 'none';
    copyButton.style.borderRadius = '10px';
    copyButton.style.cursor = 'pointer';
    copyButton.style.transition = 'transform 0.1s ease';
    copyButton.style.backgroundColor = backgroundColor;
    copyButton.style.color = 'white';
    copyButton.classList.add('copy-button');
    copyButton.style.top = (50 + 60 * (document.querySelectorAll('button.copy-button').length)) + 'px';

    // 绑定点击事件
    copyButton.addEventListener('click', function () {
        copyToClipboard(content);
    });

    // 按钮点击时的交互效果（仅缩小，不变色）
    copyButton.addEventListener('mousedown', function () {
        copyButton.style.transform = 'scale(0.9)'; // 按下时缩小
    });

    copyButton.addEventListener('mouseup', function () {
        copyButton.style.transform = 'scale(1)'; // 松开时恢复大小
    });

    document.body.appendChild(copyButton);
}

/// 获取作者信息
async function getAuthorInfo() {
    // 移除旧的按钮
    const oldButtons = document.querySelectorAll('button.copy-button');
    oldButtons.forEach(button => button.remove());

    // 获取新的作者信息
    const authorInfo = await exInfo();
    if (authorInfo && authorInfo.user_id && authorInfo.user_name) {
        const authorInfoJson = JSON.stringify(authorInfo, null, 4);
        createCopyButton('复制全部', authorInfoJson, 'red');
        createCopyButton('作者名称', authorInfo.user_name, 'green');
        createCopyButton('作者 ID', authorInfo.user_id, 'blue');
    }
}

// 创建“辅助插入”按钮并填充表单
function createAssistInsertButton(dialog) {
    if (dialog.querySelector('.assist-insert-button')) return;

    const assistButton = document.createElement('button');
    assistButton.textContent = '一键填充';
    assistButton.className = 'assist-insert-button el-button el-button--primary';
    assistButton.style.marginLeft = '10px';

    assistButton.addEventListener('click', async () => {
        const clipboardContent = await getClipboardContent();
        if (!clipboardContent) {
            alert('剪贴板中没有内容或无法读取！');
            return;
        }

        try {
            const data = JSON.parse(clipboardContent);
            if (!data.user_name || !data.user_id) {
                alert('剪贴板数据格式不正确！');
                return;
            }

            const vueInstance = document.querySelector('#app').__vue__;

            // 检查是否是“新媒体矩阵”页面的“添加账号”弹窗
            if (dialog.classList.contains('add-account')) {
                // 自动切换到“批量添加”标签
                vueInstance.activeName = 'third';

                // 格式化数据为 user_name,user_id
                const formattedData = `${data.user_name},${data.user_id}`;
                vueInstance.excelRows = formattedData;

                console.log('已切换到批量添加并填充数据:', formattedData);
            } else {
                // 默认填充逻辑（适用于其他页面，如“账号库”）
                vueInstance.targetRow.name = data.user_name;
                vueInstance.targetRow.code = data.user_id;
                vueInstance.targetRow.plat = data.plat || '';
            }

            console.log('已从剪贴板填充数据:', data);
        } catch (e) {
            alert('剪贴板数据解析失败，请确保复制了有效的JSON格式数据！');
            console.error(e);
        }
    });

    const footer = dialog.querySelector('.el-dialog__footer .dialog-footer');
    if (footer) {
        footer.appendChild(assistButton);
    } else {
        const body = dialog.querySelector('.el-dialog__body');
        if (body) body.appendChild(assistButton);
    }
}

// 创建“辅助插入”按钮并填充表单
function createAssistInsertButton1(dialog) {
    if (dialog.querySelector('.assist-insert-button')) return;

    const assistButton = document.createElement('button');
    assistButton.textContent = '一键填充';
    assistButton.className = 'assist-insert-button el-button el-button--primary';
    assistButton.style.marginLeft = '10px';

    assistButton.addEventListener('click', async () => {
        const clipboardContent = await getClipboardContent();
        if (!clipboardContent) {
            alert('剪贴板中没有内容或无法读取！');
            return;
        }

        try {
            const data = JSON.parse(clipboardContent);
            if (!data.user_name || !data.user_id) {
                alert('剪贴板数据格式不正确！');
                return;
            }

            const vueInstance = document.querySelector('#app').__vue__;
            vueInstance.targetRow.name = data.user_name;
            vueInstance.targetRow.code = data.user_id;
            vueInstance.targetRow.plat = data.plat || '';

            console.log('已从剪贴板填充数据:', data);
        } catch (e) {
            alert('剪贴板数据解析失败，请确保复制了有效的JSON格式数据！');
            console.error(e);
        }
    });

    const footer = dialog.querySelector('.el-dialog__footer .dialog-footer');
    if (footer) {
        footer.appendChild(assistButton);
    } else {
        const body = dialog.querySelector('.el-dialog__body');
        if (body) body.appendChild(assistButton);
    }
}
// 使用MutationObserver监听弹窗出现
const dialogObserver = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
        if (mutation.type === 'childList') {
            const dialogs = document.querySelectorAll('.el-dialog__wrapper');
            dialogs.forEach(dialog => {
                if (dialog.style.display !== 'none') {
                    createAssistInsertButton(dialog);
                }
            });
        }
    });
});

// 开始监听页面变化
dialogObserver.observe(document.body, { childList: true, subtree: true });

// 初始检查页面是否已有弹窗
document.querySelectorAll('.el-dialog__wrapper').forEach(dialog => {
    if (dialog.style.display !== 'none') {
        createAssistInsertButton(dialog);
    }
});

// 监听页面 URL 变化
window.addEventListener('popstate', async function () {
    await getAuthorInfo();  // 页面状态变化时获取并更新信息
});

window.addEventListener('hashchange', async function () {
    await getAuthorInfo();  // 页面 hash 变化时获取并更新信息
});

// 等待网页完成加载
window.addEventListener('load', async function () {
    await getAuthorInfo();
});

// 点击页面时重新获取作者信息
window.addEventListener('click', async function () {
    await getAuthorInfo();
});